﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using Hi_Baidu.Encrypt;

namespace Hi_Baidu.User.Serializable
{
    /// <summary>
    ///     提供了加密的可序列化类保存的基本操作方法
    /// </summary>
    [Serializable]
    public class EncryptSerializable : Serializable
    {
        /// <summary>
        ///     加密用户可序列化类型
        /// </summary>
        /// <param name="FileName" type="string">
        ///     <para>
        ///         加密的文件全路径
        ///     </para>
        /// </param>
        /// <param name="Key" type="string">
        ///     <para>
        ///         唯一标示
        ///     </para>
        /// </param>
        public EncryptSerializable(String FileName, String Key)
            : base(Key, true)
        {
            _DeEncryptStream = this;
            _FileName = FileName;
            _EType = EncryptType.ENCRYPT;
        }

        /// <summary>
        ///     解密用户可序列化类型
        /// </summary>
        /// <param name="EncryptStream" type="System.IO.MemoryStream">
        ///     <para>
        ///         当前加密流
        ///     </para>
        /// </param>
        /// <param name="Key" type="string">
        ///     <para>
        ///         唯一标示
        ///     </para>
        /// </param>
        public EncryptSerializable(MemoryStream EncryptStream, String Key)
            : base(Key, true)
        {
            _EncryptStream = EncryptStream;
            _EType = EncryptType.DEENCRYPT;
            DeEncrpt();
        }


        private EncryptType _EType;
        private enum EncryptType
        {
            ENCRYPT,
            DEENCRYPT
        }

        private String _FileName;
        /// <summary>
        ///     序列化文件名
        /// </summary>
        public String FileName
        {
            get { return _FileName; }
        }

        private MemoryStream _EncryptStream;
        /// <summary>
        ///     加密后的可序列化类数据流
        /// </summary>
        public MemoryStream EncryptStream
        {
            get { return _EncryptStream; }
        }

        private EncryptSerializable _DeEncryptStream;
        /// <summary>
        ///     未加密的可序列化类数据流
        /// </summary>
        public EncryptSerializable DeEncryptStream
        {
            get { return _DeEncryptStream; }
        }

        /// <summary>
        ///     加密当前可序列化类
        /// </summary>
        public void Encrpt()
        {
            if(_EType == EncryptType.ENCRYPT)
            {
                //如果文件存在，则删除文件
                if (File.Exists(_FileName))
                {
                    File.Delete(_FileName);
                }
                //得到序列化类
                using (MemoryStream MS = new MemoryStream())
                {
                    BinaryFormatter BF = new BinaryFormatter();
                    BF.Serialize(MS, this);
                    //创建加密后的序列化流
                    this._EncryptStream = new MemoryStream();
                    byte[] EncryptData = Encrypt_TEA.Encrypt(MS.GetBuffer());
                    this._EncryptStream.Write(EncryptData, 0, EncryptData.Length);
                    this._EncryptStream.Position = 0;
                }
            }
        }

        /// <summary>
        ///     解密当前可序列化类
        /// </summary>
        public void DeEncrpt()
        {
            if (_EType == EncryptType.DEENCRYPT)
            {
                //得到序列化类
                using (MemoryStream MS = new MemoryStream())
                {
                    byte[] DeEncryptData = Encrypt_TEA.Decrypt(_EncryptStream.GetBuffer());
                    MS.Write(DeEncryptData, 0, DeEncryptData.Length);
                    MS.Position = 0;
                    BinaryFormatter BF = new BinaryFormatter();
                    _DeEncryptStream = (EncryptSerializable)BF.Deserialize(MS);
                }
            }
        }

        public override bool Save(string FilePath)
        {
            Encrpt();
            //如果文件存在，则删除文件
            if (File.Exists(FilePath))
            {
                File.Delete(FilePath);
            }
            try
            {
                //创建
                using (FileStream FS = new FileStream(FilePath, FileMode.Create))
                {
                    byte[] EncryptData = _EncryptStream.GetBuffer();
                    FS.Write(EncryptData, 0, EncryptData.Length);
                    FS.Flush();
                }
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}
